home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / GW AdaEd 1.4.2 / GWAdaDemos / NYUDemos / PAGER_PART2.ADA < prev    next >
Text File  |  1994-01-09  |  27KB  |  855 lines

  1. --===========================================================================
  2. ---------------------------- PROCEDURE PARSER -------------------------------
  3. --===========================================================================
  4. -- PARSER parses a LINE and returns the number of tokens in that LINE
  5. -- and the first token as COMMAND (converted to lower-case) with the
  6. -- rest of the tokens in ARGS (a linked list of argument LINEs)
  7.  
  8. with LINE_DEFINITION;
  9. use  LINE_DEFINITION;
  10. procedure PARSER(INLINE  : in LINE_DEFINITION.LINE;
  11.          NARGS   : out NATURAL;
  12.          COMMAND : out LINE_DEFINITION.LINE;
  13.          ARGS    : in out LINE_DEFINITION.LINE_LIST) is
  14.  
  15.     ROVER    : NATURAL;
  16.     LROVER   : LINE_DEFINITION.LINE_LIST := null;
  17.     LFIRST   : LINE_DEFINITION.LINE_LIST := null;
  18.     LCOMMAND : LINE_DEFINITION.LINE;
  19.     LTEMP    : LINE_DEFINITION.LINE;
  20.     LARGS    : NATURAL                   := 0;
  21.  
  22.     procedure SKIP_SPACES is
  23.     begin
  24.     while INLINE.CONTENT(ROVER) <= ' ' and ROVER <= INLINE.LAST loop
  25.         ROVER := ROVER + 1;
  26.     end loop;
  27.     end SKIP_SPACES;
  28.  
  29.     procedure EXTRACT(ITEM : out LINE_DEFINITION.LINE) is
  30.     EXTRACT_ROVER : NATURAL := 0;
  31.     begin
  32.     while INLINE.CONTENT(ROVER) > ' ' and ROVER <= INLINE.LAST loop
  33.         EXTRACT_ROVER := EXTRACT_ROVER + 1;
  34.         ITEM.CONTENT(EXTRACT_ROVER) := INLINE.CONTENT(ROVER);
  35.         ROVER := ROVER + 1;
  36.     end loop;
  37.     ITEM.LAST := EXTRACT_ROVER;
  38.     end EXTRACT;
  39.  
  40. begin
  41.     COMMAND.LAST := 0;
  42.     ROVER := INLINE.CONTENT'FIRST;
  43.     SKIP_SPACES;
  44.     if ROVER <= INLINE.LAST then
  45.     EXTRACT(LCOMMAND);
  46.     LCOMMAND.LAST := LCOMMAND.LAST + 1;
  47.     LCOMMAND.CONTENT(LCOMMAND.LAST) := ' ';
  48.     COMMAND := LINE_DEFINITION.TOLOWER(LCOMMAND);
  49.     LARGS := 1;
  50.         LROVER := ARGS;
  51.     while ROVER <= INLINE.LAST loop
  52.         SKIP_SPACES;
  53.         if ROVER <= INLINE.LAST then
  54.         EXTRACT(LTEMP);
  55.         if ARGS = null then
  56.             ARGS := new LINE_DEFINITION.LINE_LIST_ELEMENT;
  57.             LROVER := ARGS;
  58.             LROVER.NEXT := null;
  59.         end if;
  60.         LROVER.CONTENT := LTEMP;
  61.         LARGS := LARGS + 1;
  62.                 if LROVER.NEXT = null then
  63.                     LROVER.NEXT := new LINE_DEFINITION.LINE_LIST_ELEMENT;
  64.                 end if;
  65.                 LROVER := LROVER.NEXT;
  66.         end if;
  67.     end loop;
  68.     end if;
  69.     NARGS := LARGS;
  70. end PARSER;
  71.  
  72. --===========================================================================
  73. ---------------------------- PACKAGE PAGED_FILE -----------------------------
  74. --===========================================================================
  75. with LINE_DEFINITION;
  76. package PAGED_FILE is
  77.  
  78.     procedure COMPUTE_CHECKSUM (NARGS   : in NATURAL;
  79.                                 ARGLIST : in LINE_DEFINITION.LINE_LIST);
  80.     -- Compute the checksum of a paged file
  81.  
  82.     procedure MAKE_INCLUDE_FILE (NARGS   : in NATURAL;
  83.                                  ARGLIST : in LINE_DEFINITION.LINE_LIST);
  84.     -- Create an include file which names the elements of a paged file
  85.  
  86.     procedure LIST (NARGS   : in NATURAL;
  87.                     ARGLIST : in LINE_DEFINITION.LINE_LIST);
  88.     -- List the names of the elements of a paged file
  89.  
  90.     procedure CREATE (NARGS   : in NATURAL;
  91.                       ARGLIST : in LINE_DEFINITION.LINE_LIST);
  92.     -- Create a paged file
  93.  
  94.     procedure UNPAGE (NARGS   : in NATURAL;
  95.                       ARGLIST : in LINE_DEFINITION.LINE_LIST);
  96.     -- Extract the elements of a paged file
  97.  
  98. end PAGED_FILE;
  99.  
  100. with INCLUDE_FILE, INPUT_FILE, OUTPUT_FILE, PARSER;
  101. with TEXT_IO;
  102. package body PAGED_FILE is
  103.  
  104.     INLINE          : LINE_DEFINITION.LINE;
  105.  
  106.     --=======================================================================
  107.     -- PAGED_FILE, Support Utilities
  108.     --=======================================================================
  109.  
  110.     use  LINE_DEFINITION;
  111.  
  112.     -- Determine if ITEM contains a BANNER or COMMENT_BANNER
  113.     function IS_BANNER(ITEM : in LINE_DEFINITION.LINE) return BOOLEAN is
  114.     RESULT : BOOLEAN;
  115.     begin
  116.     if ITEM.LAST >= LINE_DEFINITION.BANNER'LENGTH and then
  117.       ITEM.CONTENT(1 .. LINE_DEFINITION.BANNER'LENGTH) =
  118.       LINE_DEFINITION.BANNER then
  119.         RESULT := TRUE;
  120.     elsif ITEM.LAST >= LINE_DEFINITION.COMMENT_BANNER'LENGTH and then
  121.       ITEM.CONTENT(1 .. LINE_DEFINITION.COMMENT_BANNER'LENGTH) =
  122.       LINE_DEFINITION.COMMENT_BANNER then
  123.         RESULT := TRUE;
  124.     else
  125.         RESULT := FALSE;
  126.     end if;
  127.     return RESULT;
  128.     end IS_BANNER;
  129.  
  130.     -- Package to handle line counting
  131.     package COUNTER is
  132.  
  133.         -- Reset the Counter
  134.     procedure SET;
  135.  
  136.         -- Increment the Counter
  137.     procedure INCREMENT;
  138.  
  139.         -- Print the counter
  140.     procedure PRINT;
  141.  
  142.     end COUNTER;
  143.  
  144.     package body COUNTER is
  145.  
  146.     type LINE_COUNT is range 0 .. 10001;
  147.     package LINE_COUNT_IO is new TEXT_IO.INTEGER_IO(LINE_COUNT);
  148.  
  149.     LCOUNT : LINE_COUNT;
  150.  
  151.         -- Reset the LCOUNT variable
  152.     procedure SET is
  153.     begin
  154.         LCOUNT := 0;
  155.     end SET;
  156.  
  157.         -- Increment the LCOUNT variable
  158.     procedure INCREMENT is
  159.     begin
  160.         if LCOUNT < LINE_COUNT'LAST then
  161.         LCOUNT := LCOUNT + 1;
  162.         end if;
  163.     end INCREMENT;
  164.  
  165.         -- Print a count of the number of lines and reset the LCOUNT variable
  166.     procedure PRINT is
  167.     begin
  168.         TEXT_IO.PUT(" -- ");
  169.         if LCOUNT = LINE_COUNT'LAST then
  170.         TEXT_IO.PUT("More Than" & LINE_COUNT'IMAGE(LINE_COUNT'LAST -
  171.           1));
  172.         else
  173.         LINE_COUNT_IO.PUT(LCOUNT, 1);
  174.         end if;
  175.         TEXT_IO.PUT_LINE(" Lines");
  176.         LCOUNT := 0;
  177.     end PRINT;
  178.  
  179.     end COUNTER;
  180.  
  181.     --=======================================================================
  182.     -- PAGED_FILE, COMPUTE_CHECKSUM Command
  183.     --=======================================================================
  184.     procedure COMPUTE_CHECKSUM (NARGS   : in NATURAL;
  185.                                 ARGLIST : in LINE_DEFINITION.LINE_LIST) is
  186.     CHECKSUM : INTEGER;
  187.     package VALUE_IO is new TEXT_IO.INTEGER_IO(INTEGER);
  188.     begin
  189.     if NARGS = 1 then
  190.         TEXT_IO.PUT_LINE(" CHECK Command requires the name of a file");
  191.         TEXT_IO.PUT_LINE("   Syntax: list file_name");
  192.     else
  193.  
  194.             -- Step 1: Open the input file
  195.         INPUT_FILE.OPEN(ARGLIST.CONTENT);
  196.  
  197.             -- Step 2: Compute the Hash (Checksum)
  198.         CHECKSUM := 0;
  199.         while not INPUT_FILE.END_OF_FILE loop
  200.         INPUT_FILE.READ(INLINE);
  201.         for I in 1 .. INLINE.LAST loop
  202.             if INLINE.CONTENT(I) > ' ' then
  203.             CHECKSUM := CHECKSUM +
  204.               CHARACTER'POS(INLINE.CONTENT(I));
  205.             if CHECKSUM >= 128 then
  206.                 CHECKSUM := CHECKSUM - 128;
  207.             end if;
  208.             end if;
  209.         end loop;
  210.         end loop;
  211.         INPUT_FILE.CLOSE;
  212.  
  213.             -- Step 3: Print the result
  214.         TEXT_IO.PUT(" Pager Checksum (Hash) of " &
  215.           LINE_DEFINITION.CONVERT(ARGLIST.CONTENT) & " is ");
  216.         VALUE_IO.PUT(CHECKSUM, 1);
  217.         TEXT_IO.NEW_LINE;
  218.  
  219.     end if;
  220.  
  221.     exception
  222.     when INPUT_FILE.FILE_NOT_FOUND =>
  223.             TEXT_IO.PUT(" CHECK:");
  224.         TEXT_IO.PUT_LINE(" File " &
  225.               LINE_DEFINITION.CONVERT(ARGLIST.CONTENT) &
  226.           " not Found");
  227.     when INPUT_FILE.READ_PAST_END_OF_FILE =>
  228.             TEXT_IO.PUT(" CHECK:");
  229.         TEXT_IO.PUT_LINE(" Premature EOF on " &
  230.           LINE_DEFINITION.CONVERT(ARGLIST.CONTENT));
  231.         INPUT_FILE.CLOSE;
  232.     when others =>
  233.             TEXT_IO.PUT(" CHECK:");
  234.         TEXT_IO.PUT_LINE(" Unexpected Error");
  235.         INPUT_FILE.CLOSE;
  236.  
  237.     end COMPUTE_CHECKSUM;
  238.  
  239.     --=======================================================================
  240.     -- PAGED_FILE, MAKE_INCLUDE_FILE Command
  241.     --=======================================================================
  242.     procedure MAKE_INCLUDE_FILE (NARGS   : in NATURAL;
  243.                                  ARGLIST : in LINE_DEFINITION.LINE_LIST) is
  244.     IN_FILE   : BOOLEAN;
  245.         ARG_ROVER : LINE_DEFINITION.LINE_LIST;
  246.     begin
  247.     if NARGS < 3 then
  248.         TEXT_IO.PUT_LINE
  249.               (" INCLUDE Command requires the name of a paged file");
  250.         TEXT_IO.PUT_LINE
  251.               ("   Syntax: include paged_file_name output_include_file");
  252.     else
  253.  
  254.             -- Step 1: Open the input and output files
  255.         COUNTER.SET;
  256.         ARG_ROVER := ARGLIST.NEXT;
  257.         INPUT_FILE.OPEN(ARGLIST.CONTENT);
  258.         OUTPUT_FILE.OPEN(ARG_ROVER.CONTENT);
  259.         OUTPUT_FILE.WRITE("-- Include file for " &
  260.           LINE_DEFINITION.CONVERT(ARGLIST.CONTENT));
  261.  
  262.             -- Step 2: Look for the first banner in the paged file
  263.         IN_FILE := TRUE;
  264.         while not INPUT_FILE.END_OF_FILE loop
  265.         INPUT_FILE.READ(INLINE);
  266.         if IS_BANNER(INLINE) then
  267.             IN_FILE := FALSE;
  268.             exit;
  269.         end if;
  270.         end loop;
  271.  
  272.             -- Step 3: If first banner not found, issue error message,
  273.             --         else process component files
  274.         if IN_FILE then
  275.         TEXT_IO.PUT_LINE
  276.                   (" File " & LINE_DEFINITION.CONVERT(ARGLIST.CONTENT) &
  277.           " does not contain any components");
  278.         else
  279.  
  280.                 -- Loop until the end of the input paged file
  281.         while not INPUT_FILE.END_OF_FILE loop
  282.  
  283.                     -- Read the next line from the input paged file
  284.             INPUT_FILE.READ(INLINE);
  285.  
  286.                     -- If we are not in the text of the file, the line just
  287.                     -- read contains the name of a new file, else it contains
  288.                     -- a line of the current component file
  289.             if not IN_FILE then
  290.  
  291.                     -- Remove leading comment character if any and print the
  292.                     -- name of the component file
  293.             if INLINE.CONTENT(1 .. 2) = "--" then
  294.                 TEXT_IO.PUT(" " &
  295.                   INLINE.CONTENT(3 .. INLINE.LAST));
  296.                 OUTPUT_FILE.WRITE
  297.                               (INLINE.CONTENT(3 .. INLINE.LAST));
  298.             else
  299.                 TEXT_IO.PUT(" " &
  300.                   INLINE.CONTENT(1 .. INLINE.LAST));
  301.                 OUTPUT_FILE.WRITE
  302.                               (INLINE.CONTENT(1 .. INLINE.LAST));
  303.             end if;
  304.  
  305.                         -- Flush the trailing banner line and note that we are
  306.                         -- now within the text of a component file
  307.             INPUT_FILE.READ(INLINE);
  308.             COUNTER.SET;
  309.             IN_FILE := TRUE;
  310.  
  311.             else
  312.  
  313.                     -- We are within the text of a component file, so check
  314.                     -- for a banner in order to determine if we are at the end
  315.                     -- of the component file
  316.             if IS_BANNER(INLINE) then
  317.                 IN_FILE := FALSE;
  318.                 COUNTER.PRINT;
  319.             else
  320.                 COUNTER.INCREMENT;
  321.             end if;
  322.  
  323.             end if;
  324.  
  325.         end loop;
  326.  
  327.         end if;
  328.  
  329.         COUNTER.PRINT;
  330.         INPUT_FILE.CLOSE;
  331.         OUTPUT_FILE.CLOSE;
  332.  
  333.     end if;
  334.  
  335.     exception
  336.     when OUTPUT_FILE.CANNOT_CREATE_FILE =>
  337.             TEXT_IO.PUT(" INCLUDE:");
  338.         TEXT_IO.PUT_LINE(" Cannot create " &
  339.           LINE_DEFINITION.CONVERT(ARG_ROVER.CONTENT));
  340.     when INPUT_FILE.FILE_NOT_FOUND =>
  341.             TEXT_IO.PUT(" INCLUDE:");
  342.         TEXT_IO.PUT_LINE
  343.               (" File " & LINE_DEFINITION.CONVERT(ARGLIST.CONTENT) &
  344.           " not Found");
  345.     when INPUT_FILE.READ_PAST_END_OF_FILE =>
  346.             TEXT_IO.PUT(" INCLUDE:");
  347.         TEXT_IO.PUT_LINE(" Premature EOF on " &
  348.           LINE_DEFINITION.CONVERT(ARGLIST.CONTENT));
  349.         INPUT_FILE.CLOSE;
  350.     when others =>
  351.             TEXT_IO.PUT(" INCLUDE:");
  352.         TEXT_IO.PUT_LINE(" Unexpected Error");
  353.         INPUT_FILE.CLOSE;
  354.  
  355.     end MAKE_INCLUDE_FILE;
  356.  
  357.     --=======================================================================
  358.     -- PAGED_FILE, LIST Command
  359.     --=======================================================================
  360.     procedure LIST (NARGS   : in NATURAL;
  361.                     ARGLIST : in LINE_DEFINITION.LINE_LIST) is
  362.     IN_FILE : BOOLEAN;
  363.     begin
  364.     if NARGS = 1 then
  365.         TEXT_IO.PUT_LINE
  366.               (" LIST Command requires the name of a paged file");
  367.         TEXT_IO.PUT_LINE
  368.               ("   Syntax: list paged_file_name");
  369.     else
  370.  
  371.             -- Step 1: Open the input file
  372.         COUNTER.SET;
  373.         INPUT_FILE.OPEN(ARGLIST.CONTENT);
  374.  
  375.             -- Step 2: Look for the first banner in the paged file
  376.         IN_FILE := TRUE;
  377.         while not INPUT_FILE.END_OF_FILE loop
  378.         INPUT_FILE.READ(INLINE);
  379.         if IS_BANNER(INLINE) then
  380.             IN_FILE := FALSE;
  381.             exit;
  382.         end if;
  383.         end loop;
  384.  
  385.             -- Step 3: If first banner not found, issue error message,
  386.             --         else process component files
  387.         if IN_FILE then
  388.         TEXT_IO.PUT_LINE
  389.                   (" File " & LINE_DEFINITION.CONVERT(ARGLIST.CONTENT) &
  390.           " does not contain any components");
  391.         else
  392.  
  393.                 -- Loop until the end of the input paged file
  394.         while not INPUT_FILE.END_OF_FILE loop
  395.  
  396.                     -- Read the next line from the input paged file
  397.             INPUT_FILE.READ(INLINE);
  398.  
  399.                     -- If we are not in the text of the file, the line just
  400.                     -- read contains the name of a new file, else it contains
  401.                     -- a line of the current component file
  402.             if not IN_FILE then
  403.  
  404.                         -- Remove leading comment character if any and print
  405.                         -- the name of the component file
  406.             if INLINE.CONTENT(1 .. 2) = "--" then
  407.                 TEXT_IO.PUT(" " &
  408.                   INLINE.CONTENT(3 .. INLINE.LAST));
  409.             else
  410.                 TEXT_IO.PUT(" " &
  411.                   INLINE.CONTENT(1 .. INLINE.LAST));
  412.             end if;
  413.  
  414.                         -- Flush the trailing banner line and note that we are
  415.                         -- now within the text of a component file
  416.             INPUT_FILE.READ(INLINE);
  417.             COUNTER.SET;
  418.             IN_FILE := TRUE;
  419.  
  420.             else
  421.  
  422.                         -- We are within the text of a component file, so
  423.                         -- check for a banner in order to determine if we
  424.                         -- are at the end of the component file
  425.             if IS_BANNER(INLINE) then
  426.                 IN_FILE := FALSE;
  427.                 COUNTER.PRINT;
  428.             else
  429.                 COUNTER.INCREMENT;
  430.             end if;
  431.  
  432.             end if;
  433.  
  434.         end loop;
  435.  
  436.         end if;
  437.  
  438.         COUNTER.PRINT;
  439.         INPUT_FILE.CLOSE;
  440.  
  441.     end if;
  442.  
  443.     exception
  444.     when INPUT_FILE.FILE_NOT_FOUND =>
  445.             TEXT_IO.PUT(" LIST:");
  446.         TEXT_IO.PUT_LINE
  447.               (" File " & LINE_DEFINITION.CONVERT(ARGLIST.CONTENT) &
  448.           " not Found");
  449.     when INPUT_FILE.READ_PAST_END_OF_FILE =>
  450.             TEXT_IO.PUT(" LIST:");
  451.         TEXT_IO.PUT_LINE(" Premature EOF on " &
  452.           LINE_DEFINITION.CONVERT(ARGLIST.CONTENT));
  453.         INPUT_FILE.CLOSE;
  454.     when others =>
  455.             TEXT_IO.PUT(" LIST:");
  456.         TEXT_IO.PUT_LINE(" Unexpected Error");
  457.         INPUT_FILE.CLOSE;
  458.  
  459.     end LIST;
  460.  
  461.     --=======================================================================
  462.     -- PAGED_FILE, CREATE Command
  463.     --=======================================================================
  464.     procedure CREATE (NARGS   : in NATURAL;
  465.                       ARGLIST : in LINE_DEFINITION.LINE_LIST) is
  466.     COMPONENT_FILE_NAME : LINE_DEFINITION.LINE;
  467.     OUTPUT_FILE_NAME    : LINE_DEFINITION.LINE;
  468.         ARG_ROVER           : LINE_DEFINITION.LINE_LIST;
  469.     begin
  470.     if NARGS < 3 then
  471.         TEXT_IO.PUT_LINE
  472.               (" PAGE Command requires the name of the paged file and include file");
  473.         TEXT_IO.PUT_LINE
  474.               ("   Syntax: page [@include_file_name|file_name]+ paged_file_name");
  475.     else
  476.         ARG_ROVER := ARGLIST;
  477.             for I in 1 .. NARGS-2 loop
  478.         ARG_ROVER := ARG_ROVER.NEXT;
  479.         end loop;
  480.         OUTPUT_FILE_NAME := ARG_ROVER.CONTENT;
  481.         OUTPUT_FILE.OPEN(OUTPUT_FILE_NAME);
  482.         ARG_ROVER := ARGLIST;
  483.         for I in 1 .. NARGS-2 loop
  484.         if ARG_ROVER.CONTENT.CONTENT(1) =
  485.           INCLUDE_FILE.INCLUDE_CHARACTER then
  486.             INCLUDE_FILE.OPEN
  487.                       (LINE_DEFINITION.CONVERT(ARG_ROVER.CONTENT));
  488.             begin
  489.             loop
  490.                 INCLUDE_FILE.READ(COMPONENT_FILE_NAME);
  491.                 INPUT_FILE.OPEN(COMPONENT_FILE_NAME);
  492.                 OUTPUT_FILE.WRITE(LINE_DEFINITION.COMMENT_BANNER);
  493.                 OUTPUT_FILE.WRITE("--" &
  494.                   LINE_DEFINITION.CONVERT(COMPONENT_FILE_NAME));
  495.                 OUTPUT_FILE.WRITE(LINE_DEFINITION.COMMENT_BANNER);
  496.                 TEXT_IO.PUT(" Adding " &
  497.                   LINE_DEFINITION.CONVERT(COMPONENT_FILE_NAME));
  498.                 COUNTER.SET;
  499.                 while not INPUT_FILE.END_OF_FILE loop
  500.                 INPUT_FILE.READ(INLINE);
  501.                 OUTPUT_FILE.WRITE(INLINE);
  502.                 COUNTER.INCREMENT;
  503.                 end loop;
  504.                 COUNTER.PRINT;
  505.                 INPUT_FILE.CLOSE;
  506.             end loop;
  507.             exception
  508.             when INCLUDE_FILE.READ_PAST_END_OF_FILE |
  509.               INCLUDE_FILE.INCLUDE_FILE_EMPTY |
  510.                           INCLUDE_FILE.NESTING_LEVEL_EXCEEDED =>
  511.                             INCLUDE_FILE.STOP;
  512.             when INPUT_FILE.FILE_NOT_FOUND =>
  513.                 TEXT_IO.PUT_LINE(" File " &
  514.                   LINE_DEFINITION.CONVERT(COMPONENT_FILE_NAME) &
  515.                   " not Found");
  516.                 INCLUDE_FILE.STOP;
  517.             when others =>
  518.                 TEXT_IO.PUT_LINE
  519.                               (" Unexpected Error During Processing " &
  520.                               "of Component File " &
  521.                   LINE_DEFINITION.CONVERT(COMPONENT_FILE_NAME));
  522.                 INCLUDE_FILE.STOP;
  523.             end;
  524.         else
  525.             INPUT_FILE.OPEN(ARG_ROVER.CONTENT);
  526.             OUTPUT_FILE.WRITE(LINE_DEFINITION.COMMENT_BANNER);
  527.             OUTPUT_FILE.WRITE("--" &
  528.               LINE_DEFINITION.CONVERT(ARG_ROVER.CONTENT));
  529.             OUTPUT_FILE.WRITE(LINE_DEFINITION.COMMENT_BANNER);
  530.             TEXT_IO.PUT(" Adding " &
  531.               LINE_DEFINITION.CONVERT(ARG_ROVER.CONTENT));
  532.             COUNTER.SET;
  533.             while not INPUT_FILE.END_OF_FILE loop
  534.             INPUT_FILE.READ(INLINE);
  535.             OUTPUT_FILE.WRITE(INLINE);
  536.             COUNTER.INCREMENT;
  537.             end loop;
  538.             COUNTER.PRINT;
  539.             INPUT_FILE.CLOSE;
  540.         end if;
  541.                 ARG_ROVER := ARG_ROVER.NEXT;
  542.         end loop;
  543.             OUTPUT_FILE.CLOSE;
  544.     end if;
  545.  
  546.     exception
  547.     when OUTPUT_FILE.CANNOT_CREATE_FILE =>
  548.             TEXT_IO.PUT(" PAGE:");
  549.         TEXT_IO.PUT_LINE(" Cannot create " &
  550.           LINE_DEFINITION.CONVERT(OUTPUT_FILE_NAME));
  551.     when INCLUDE_FILE.FILE_NOT_FOUND =>
  552.             TEXT_IO.PUT(" PAGE:");
  553.         TEXT_IO.PUT_LINE(" Cannot open include file");
  554.     when others =>
  555.             TEXT_IO.PUT(" PAGE:");
  556.         TEXT_IO.PUT_LINE(" Unexpected Error");
  557.         INPUT_FILE.CLOSE;
  558.  
  559.     end CREATE;
  560.  
  561.     --=======================================================================
  562.     -- PAGED_FILE, UNPAGE Command
  563.     --=======================================================================
  564.     procedure UNPAGE (NARGS   : in NATURAL;
  565.                       ARGLIST : in LINE_DEFINITION.LINE_LIST) is
  566.     IN_FILE          : BOOLEAN;
  567.     OUTPUT_FILE_NAME : LINE_DEFINITION.LINE;
  568.     begin
  569.     if NARGS = 1 then
  570.         TEXT_IO.PUT_LINE
  571.               (" UNPAGE Command requires the name of a paged file");
  572.         TEXT_IO.PUT_LINE("   Syntax: unpage paged_file_name");
  573.     else
  574.  
  575.             -- Step 1: Open the input file
  576.         COUNTER.SET;
  577.         INPUT_FILE.OPEN(ARGLIST.CONTENT);
  578.  
  579.             -- Step 2: Look for the first banner in the paged file
  580.         IN_FILE := TRUE;
  581.         while not INPUT_FILE.END_OF_FILE loop
  582.         INPUT_FILE.READ(INLINE);
  583.         if IS_BANNER(INLINE) then
  584.             IN_FILE := FALSE;
  585.             exit;
  586.         end if;
  587.         end loop;
  588.  
  589.             -- Step 3: If first banner not found, issue error message,
  590.             --         else process component files
  591.         if IN_FILE then
  592.         TEXT_IO.PUT_LINE(" File " &
  593.                   LINE_DEFINITION.CONVERT(ARGLIST.CONTENT) &
  594.           " does not contain any components");
  595.         else
  596.  
  597.                 -- Loop until the end of the input paged file
  598.         while not INPUT_FILE.END_OF_FILE loop
  599.  
  600.                     -- Read the next line from the input paged file
  601.             INPUT_FILE.READ(INLINE);
  602.  
  603.                     -- If we are not in the text of the file, the line just
  604.                     -- read contains the name of a new file, else it contains
  605.                     -- a line of the current component file
  606.             if not IN_FILE then
  607.  
  608.                         -- Remove leading comment character if any and
  609.                         -- store the name of the component file
  610.             if INLINE.CONTENT(1 .. 2) = "--" then
  611.                 OUTPUT_FILE_NAME :=
  612.                   LINE_DEFINITION.CONVERT
  613.                                 (INLINE.CONTENT(3 .. INLINE.LAST));
  614.             else
  615.                 OUTPUT_FILE_NAME :=
  616.                   LINE_DEFINITION.CONVERT
  617.                                 (INLINE.CONTENT(1 .. INLINE.LAST));
  618.             end if;
  619.  
  620.                         -- Open the new component file
  621.             OUTPUT_FILE.OPEN(OUTPUT_FILE_NAME);
  622.             TEXT_IO.PUT(" Extracting " &
  623.               LINE_DEFINITION.CONVERT(OUTPUT_FILE_NAME));
  624.  
  625.                         -- Flush the trailing banner line and note that we are
  626.                         -- now within the text of a component file
  627.             INPUT_FILE.READ(INLINE);
  628.             IN_FILE := TRUE;
  629.             COUNTER.SET;
  630.  
  631.             else
  632.  
  633.                         -- We are within the text of a component file, so
  634.                         -- check for a banner in order to determine if we
  635.                         -- are at the end of the component file
  636.             if IS_BANNER(INLINE) then
  637.                 OUTPUT_FILE.CLOSE;
  638.                 IN_FILE := FALSE;
  639.                 COUNTER.PRINT;
  640.             else
  641.                 OUTPUT_FILE.WRITE(INLINE);
  642.                 COUNTER.INCREMENT;
  643.             end if;
  644.  
  645.             end if;
  646.  
  647.         end loop;
  648.  
  649.         OUTPUT_FILE.CLOSE;
  650.  
  651.         end if;
  652.  
  653.         COUNTER.PRINT;
  654.         INPUT_FILE.CLOSE;
  655.  
  656.     end if;
  657.  
  658.     exception
  659.     when OUTPUT_FILE.CANNOT_CREATE_FILE =>
  660.             TEXT_IO.PUT(" UNPAGE:");
  661.         TEXT_IO.PUT_LINE(" Cannot create " &
  662.           LINE_DEFINITION.CONVERT(OUTPUT_FILE_NAME));
  663.     when INPUT_FILE.FILE_NOT_FOUND =>
  664.             TEXT_IO.PUT(" UNPAGE:");
  665.         TEXT_IO.PUT_LINE(" File " &
  666.               LINE_DEFINITION.CONVERT(ARGLIST.CONTENT) &
  667.           " not Found");
  668.     when INPUT_FILE.READ_PAST_END_OF_FILE =>
  669.             TEXT_IO.PUT(" UNPAGE:");
  670.         TEXT_IO.PUT_LINE(" Premature EOF on " &
  671.           LINE_DEFINITION.CONVERT(ARGLIST.CONTENT));
  672.         INPUT_FILE.CLOSE;
  673.     when others =>
  674.             TEXT_IO.PUT(" UNPAGE:");
  675.         TEXT_IO.PUT_LINE(" Unexpected Error");
  676.         INPUT_FILE.CLOSE;
  677.  
  678.     end UNPAGE;
  679.  
  680. end PAGED_FILE;
  681.  
  682. --===========================================================================
  683. --------------------------------- MAINLINE ----------------------------------
  684. --===========================================================================
  685. with LINE_DEFINITION, PAGED_FILE, PARSER;
  686. use  LINE_DEFINITION;
  687. with TEXT_IO;
  688. with CLI;
  689. procedure PAGER2 is
  690.  
  691.     TITLE           : constant STRING := "PAGER2, Ada Version 1.1";
  692.  
  693.     INLINE          : LINE_DEFINITION.LINE;
  694.  
  695.     NARGS           : NATURAL;
  696.     COMMAND         : LINE_DEFINITION.LINE;
  697.     ARGLIST         : LINE_DEFINITION.LINE_LIST;
  698.     ARG_ROVER       : LINE_DEFINITION.LINE_LIST;
  699.  
  700.     -- Command Verbs
  701.     HELP_COMMAND    : constant STRING := "help ";
  702.     H_COMMAND       : constant STRING := "h ";
  703.     EXIT_COMMAND    : constant STRING := "exit ";
  704.     X_COMMAND       : constant STRING := "x ";    -- same as exit
  705.     CHECK_COMMAND   : constant STRING := "check ";
  706.     C_COMMAND       : constant STRING := "c ";    -- same as check
  707.     INCLUDE_COMMAND : constant STRING := "include ";
  708.     I_COMMAND       : constant STRING := "i ";    -- same as include
  709.     LIST_COMMAND    : constant STRING := "list ";
  710.     L_COMMAND       : constant STRING := "l ";    -- same as list
  711.     PAGE_COMMAND    : constant STRING := "page ";
  712.     P_COMMAND       : constant STRING := "p ";    -- same as page
  713.     UNPAGE_COMMAND  : constant STRING := "unpage ";
  714.     U_COMMAND       : constant STRING := "u ";    -- same as unpage
  715.  
  716.     --=======================================================================
  717.     -- PAGER2, Support Utilities
  718.     --=======================================================================
  719.  
  720.     -- Determine if COMMAND contains one of the two target command strings
  721.     function IS_COMMAND(TARGET1_COMMAND, TARGET2_COMMAND : in STRING)
  722.             return BOOLEAN is
  723.         START : NATURAL;
  724.     begin
  725.         if COMMAND.CONTENT(1) = '-' then
  726.             START := 2;
  727.         else
  728.             START := 1;
  729.         end if;
  730.     if COMMAND.CONTENT(START .. TARGET1_COMMAND'LENGTH + START - 1)
  731.               = TARGET1_COMMAND or
  732.       COMMAND.CONTENT(START .. TARGET2_COMMAND'LENGTH + START - 1)
  733.               = TARGET2_COMMAND then
  734.         return TRUE;
  735.     else
  736.         return FALSE;
  737.     end if;
  738.     end IS_COMMAND;
  739.  
  740.     --=======================================================================
  741.     -- PAGER2, HELP Command
  742.     --=======================================================================
  743.     procedure HELP is
  744.     procedure SPACER is
  745.     begin
  746.         TEXT_IO.PUT("                  ");
  747.     end SPACER;
  748.     begin
  749.     TEXT_IO.PUT_LINE(" Command Summary");
  750.     TEXT_IO.PUT_LINE("  help or h   - this summary");
  751.     SPACER;
  752.     TEXT_IO.PUT_LINE("Syntax: help");
  753.     TEXT_IO.PUT_LINE("  exit or x   - exit from program");
  754.     SPACER;
  755.     TEXT_IO.PUT_LINE("Syntax: exit");
  756.     TEXT_IO.PUT_LINE
  757.           ("  include or i- list components into an include file");
  758.     SPACER;
  759.     TEXT_IO.PUT_LINE
  760.           ("Syntax: include paged_file_name output_include_file");
  761.     TEXT_IO.PUT_LINE("  list or l   - list components of paged file");
  762.     SPACER;
  763.     TEXT_IO.PUT_LINE("Syntax: list paged_file_name");
  764.     TEXT_IO.PUT_LINE
  765.           ("  page or p   - create paged file from include file");
  766.     SPACER;
  767.     TEXT_IO.PUT_LINE
  768.           ("Syntax: page [@include_file_name|file_name]+ paged_file_name");
  769.     TEXT_IO.PUT_LINE
  770.           ("  unpage or u - extract components from paged file");
  771.     SPACER;
  772.     TEXT_IO.PUT_LINE("Syntax: unpage paged_file_name");
  773.     end HELP;
  774.  
  775. --=======================================================================
  776. -- PAGER2, Mainline
  777. --=======================================================================
  778. begin
  779.     CLI.INITIALIZE ("PAGER2", "Enter verb and arguments: ");
  780.  
  781.     -- Interactive mode if no arguments
  782.     if CLI.ARGC = 1 then
  783.     TEXT_IO.PUT_LINE(TITLE);
  784.     TEXT_IO.PUT_LINE("Type 'h' for Help");
  785.     loop
  786.         begin
  787.         TEXT_IO.PUT("PAGER2> ");
  788.         TEXT_IO.GET_LINE(INLINE.CONTENT, INLINE.LAST);
  789.         PARSER(INLINE, NARGS, COMMAND, ARGLIST);
  790.         if NARGS > 0 then
  791.             exit when IS_COMMAND(EXIT_COMMAND, X_COMMAND);
  792.             if IS_COMMAND(HELP_COMMAND, H_COMMAND) then
  793.             HELP;
  794.             elsif IS_COMMAND(CHECK_COMMAND, C_COMMAND) then
  795.             PAGED_FILE.COMPUTE_CHECKSUM (NARGS, ARGLIST);
  796.             elsif IS_COMMAND(INCLUDE_COMMAND, I_COMMAND) then
  797.             PAGED_FILE.MAKE_INCLUDE_FILE (NARGS, ARGLIST);
  798.             elsif IS_COMMAND(LIST_COMMAND, L_COMMAND) then
  799.             PAGED_FILE.LIST (NARGS, ARGLIST);
  800.             elsif IS_COMMAND(PAGE_COMMAND, P_COMMAND) then
  801.             PAGED_FILE.CREATE (NARGS, ARGLIST);
  802.             elsif IS_COMMAND(UNPAGE_COMMAND, U_COMMAND) then
  803.             PAGED_FILE.UNPAGE (NARGS, ARGLIST);
  804.             else
  805.             TEXT_IO.PUT_LINE(" Invalid Command: " &
  806.               LINE_DEFINITION.CONVERT(COMMAND));
  807.             end if;
  808.         end if;
  809.         exception
  810.         when others =>
  811.             null;
  812.         end;
  813.     end loop;
  814.     -- Non-interactive mode if one or more arguments
  815.     else
  816.     COMMAND := TOLOWER(LINE_DEFINITION.CONVERT(CLI.ARGV(1) & " "));
  817.     NARGS := CLI.ARGC - 1;
  818.     ARGLIST := null;
  819.     for I in 2 .. CLI.ARGC - 1 loop
  820.         if I = 2 then
  821.         ARGLIST := new LINE_DEFINITION.LINE_LIST_ELEMENT;
  822.         ARG_ROVER := ARGLIST;
  823.         else
  824.         ARG_ROVER.NEXT := new LINE_DEFINITION.LINE_LIST_ELEMENT;
  825.         ARG_ROVER := ARG_ROVER.NEXT;
  826.         end if;
  827.         ARG_ROVER.NEXT := null;
  828.         ARG_ROVER.CONTENT := LINE_DEFINITION.CONVERT(CLI.ARGV(I));
  829.     end loop;
  830.     if NARGS > 0 then
  831.         if IS_COMMAND(HELP_COMMAND, H_COMMAND) then
  832.         HELP;
  833.         elsif IS_COMMAND(CHECK_COMMAND, C_COMMAND) then
  834.         PAGED_FILE.COMPUTE_CHECKSUM (NARGS, ARGLIST);
  835.         elsif IS_COMMAND(INCLUDE_COMMAND, I_COMMAND) then
  836.         PAGED_FILE.MAKE_INCLUDE_FILE (NARGS, ARGLIST);
  837.         elsif IS_COMMAND(LIST_COMMAND, L_COMMAND) then
  838.         PAGED_FILE.LIST (NARGS, ARGLIST);
  839.         elsif IS_COMMAND(PAGE_COMMAND, P_COMMAND) then
  840.         PAGED_FILE.CREATE (NARGS, ARGLIST);
  841.         elsif IS_COMMAND(UNPAGE_COMMAND, U_COMMAND) then
  842.         PAGED_FILE.UNPAGE (NARGS, ARGLIST);
  843.         elsif IS_COMMAND(EXIT_COMMAND, X_COMMAND) then
  844.         null;
  845.         else
  846.         TEXT_IO.PUT_LINE(" Invalid Command: " &
  847.           LINE_DEFINITION.CONVERT(COMMAND));
  848.         end if;
  849.     end if;
  850.     end if;
  851. exception
  852.     when others =>
  853.     null;
  854. end PAGER2;
  855.